#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <assert.h>

const int    Nx      = 15;
const int    Npas    = 5;
const double lambda  = 1.0;

#define LIQUID   0
#define BUBBLE   1
#define INACTIVE 2

int    *Cavity = NULL; // Tableau of Status
double *WakeUp = NULL; // WakeUp times...

//______________________________________________________________________________
//
// Allocate memory...
//______________________________________________________________________________
void CreateFields()
{
    Cavity = (int    *) malloc(Nx*sizeof(int)   );
    WakeUp = (double *) malloc(Nx*sizeof(double));
}

//______________________________________________________________________________
//
// Clean up...
//______________________________________________________________________________
void DeleteFields()
{
    free(WakeUp);
    free(Cavity);
}

//______________________________________________________________________________
//
// Set cavities to liquid and  prepare wake up times
//______________________________________________________________________________
void InitFields()
{
    int i;
    
    for(i=0;i<Nx;++i)
    {
        const double rnd = drand48();        // rnd in ]0:1[
        const double tmx = -log(rnd)/lambda; // exponential time
        
        Cavity[i] = LIQUID;
        WakeUp[i] = tmx;
    }
}

//______________________________________________________________________________
//
// Detect next wake up time
//______________________________________________________________________________
int FindNextCavitation( double *tmin, int *imin )
{
    int i;
    assert(tmin!=NULL);
    assert(imin!=NULL);
    
    *imin = -1;
    *tmin = -1;
    for(i=0;i<Nx;++i)
    {
        // test for liquid
        double tmx = 0;
        if( Cavity[i] != LIQUID )
            continue;
        
        // get cavity time
        tmx = WakeUp[i];
        
        if( *imin < 0 )
        {
            // no liquid met so far
            *imin = i;
            *tmin = tmx;
        }
        else
        {
            // we already have a value
            assert(*imin>=0);
            assert(*tmin>=0);
            if( tmx < *tmin)
            {
                *tmin = tmx;
                *imin = i;
            }
        }
        
    }
    
    return *imin>=0 ? 1 : 0;
}

//______________________________________________________________________________
//
// Process Possible Cavitation
//______________________________________________________________________________
void ProcessCavitation( int imin )
{
    Cavity[imin] = BUBBLE;
}


//______________________________________________________________________________
//
// main program
//______________________________________________________________________________
int main( int argc, char *argv[] )
{
    srand48(time(NULL));
    
    CreateFields();
    
    InitFields();
    
    int    imin = 0;
    double tmin = 0;
    
    while(FindNextCavitation( &tmin, &imin))
    {
        printf("Cavitation @%d, time=%g\n", imin, tmin);
        ProcessCavitation(imin);
    }
    
    DeleteFields();
    
    return 0;
}

